package classLoader;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * @author
 * @date 2021年11月26日 21:27
 * @description 自定义类加载器实现热加载，有点问题存在，第一次会出现异常。
 */
public class CustomClassLoader extends ClassLoader{

//    private static final String CLASS_FILE_SUFFIX = ".class";
//
//
//    //AppClassLoader的父类加载器
//    private ClassLoader extClassLoader;
//
//
//    @Override
//    protected Class<?> findClass(String name)  {
//        byte[] bytes = loadClassData(name);
//        return defineClass(name, bytes, 0, bytes.length);
//    }
//
//    public CustomClassLoader() {
//        ClassLoader classLoader = String.class.getClassLoader();
//
//        if (classLoader == null) {
//            classLoader = getSystemClassLoader();
//            while (classLoader.getParent() != null) {
//                classLoader = classLoader.getParent();
//            }
//
//        }
//
//        this.extClassLoader = classLoader;
//
//
//    }
//
//
//    @Override
//    protected Class<?> loadClass(String name, boolean resolve)  {
//        Class<?> cls = null;
//
//        cls = findLoadedClass(name);
//
//        if (cls != null) {
//            return cls;
//        }
//        ClassLoader classLoader = getExtClassLoader();
//
//
//        try {
//            cls = classLoader.loadClass(name);
//            if (cls != null) {
//                return cls;
//            }
//
//        } catch (ClassNotFoundException e) {
//            System.out.println("类文件名称"+name);
//            e.printStackTrace();
//        }
//
//        cls = findClass(name);
//        return cls;
//    }
//
//    private byte[] loadClassData(String className) {
//        InputStream in = getClass().getClassLoader().getResourceAsStream(className.replace(".", "/") + CLASS_FILE_SUFFIX);
//
//        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//
//        int len = 0;
//
//
//        try {
//            while((len=in.read())!=-1){
//                byteArrayOutputStream.write(len);
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//
//        return byteArrayOutputStream.toByteArray();
//
//
//
//    }
//
//
//    public ClassLoader getExtClassLoader(){
//        return this.extClassLoader;
//    }
//


    private static final String CLASS_FILE_SUFFIX = ".class";

    //AppClassLoader的父类加载器
    private ClassLoader extClassLoader;

    public CustomClassLoader(){
        ClassLoader j = String.class.getClassLoader();
        if (j == null) {
            j = getSystemClassLoader();
            while (j.getParent() != null) {
                j = j.getParent();
            }
        }
        this.extClassLoader = j ;
    }

    @Override
    protected Class<?> loadClass(String name, boolean resolve){

        Class cls = null;
        cls = findLoadedClass(name);
        if (cls != null){
            return cls;
        }
        if ("classLoader.TestModify".equals(name)){
            try {
                cls = getSystemClassLoader().loadClass(name);
            } catch (ClassNotFoundException e) {

            }
            return cls;
        }
        //获取ExtClassLoader
        ClassLoader extClassLoader = getExtClassLoader() ;
        //确保自定义的类不会覆盖Java的核心类
        try {
            cls = extClassLoader.loadClass(name);
            if (cls != null){
                return cls;
            }
        }catch (ClassNotFoundException e ){
                        System.out.println("类文件名称"+name);

            e.printStackTrace();
        }
        cls = findClass(name);
        return cls;
    }

    @Override
    public Class<?> findClass(String name) {
        byte[] bt = loadClassData(name);
        return defineClass(name, bt, 0, bt.length);
    }

    private byte[] loadClassData(String className) {
        // 读取Class文件呢
        InputStream is = getClass().getClassLoader().getResourceAsStream(className.replace(".", "/")+CLASS_FILE_SUFFIX);
        ByteArrayOutputStream byteSt = new ByteArrayOutputStream();
        // 写入byteStream
        int len =0;
        try {
            while((len=is.read())!=-1){
                byteSt.write(len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 转换为数组
        return byteSt.toByteArray();
    }

    public ClassLoader getExtClassLoader(){
        return extClassLoader;
    }



}
